package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.mapper.*;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.common.annotation.TingShuCache;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.constant.TingShuMqConstants;
import com.atguigu.tingshu.common.service.RabbitmqService;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.album.AlbumAttributeValue;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.AlbumStat;
import com.atguigu.tingshu.query.album.AlbumInfoQuery;
import com.atguigu.tingshu.vo.album.AlbumAttributeValueVo;
import com.atguigu.tingshu.vo.album.AlbumInfoVo;
import com.atguigu.tingshu.vo.album.AlbumListVo;
import com.atguigu.tingshu.vo.album.AlbumStatVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo> implements AlbumInfoService {
    @Resource
    private AlbumAttributeValueMapper albumAttributeValueMapper;
    @Resource
    private AlbumStatMapper albumStatMapper;
    @Resource
    private RabbitmqService rabbitmqService;
    @Resource
    private ExecutorService executorService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveAlbumInfo(AlbumInfoVo albumInfoVo) {
        AlbumInfo albumInfo = new AlbumInfo();
        //将vo中的属性值赋值给实体类
        BeanUtils.copyProperties(albumInfoVo, albumInfo);
        //设置用户id
        albumInfo.setUserId(AuthContextHolder.getUserId() == null ? 1 : AuthContextHolder.getUserId());
        //设置状态为通过
        albumInfo.setStatus(SystemConstant.ALBUM_STATUS_PASS);
        //设置免费试听条数,根据付费类型设置(会员试听6集,非会员试听3集)
        if (albumInfoVo.getPayType().equals(SystemConstant.ALBUM_PAY_TYPE_REQUIRE)) {
            albumInfo.setTracksForFree(albumInfoVo.getPayType().equals(SystemConstant.ALBUM_PAY_TYPE_VIP_FREE) ? 6 : 3);
        }
        save(albumInfo);
        Long albumInfoId = albumInfo.getId();
        //保存专辑标签值
        saveAlbumAttributeValue(albumInfoVo, albumInfoId);
        //初始化专辑统计表
        initAlbumStat(albumInfoId, SystemConstant.ALBUM_STAT_PLAY);         //播放量
        initAlbumStat(albumInfoId, SystemConstant.ALBUM_STAT_SUBSCRIBE);    //订阅量
        initAlbumStat(albumInfoId, SystemConstant.ALBUM_STAT_BROWSE);       //购买量
        initAlbumStat(albumInfoId, SystemConstant.ALBUM_STAT_COMMENT);      //评论数
        //发送消息，同步es数据
        if (albumInfo.getIsOpen().equals("1")) { //如果专辑是公开的，则发送消息
            rabbitmqService.sendMqMsg(TingShuMqConstants.ALBUM_EXCHANGE, TingShuMqConstants.ALBUM_SAVE_UPDATE_RK, albumInfoId);
        }
    }

    @Override
    public IPage<AlbumListVo> findUserAlbumPage(IPage<AlbumListVo> iPage, AlbumInfoQuery albumInfoQuery) {
        albumInfoQuery.setUserId(AuthContextHolder.getUserId() == null ? 1 : AuthContextHolder.getUserId());
        return baseMapper.findUserAlbumPage(iPage, albumInfoQuery);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeAlbumInfo(Long id) {
        this.removeById(id);
        this.albumStatMapper.delete(new LambdaQueryWrapper<AlbumStat>().eq(AlbumStat::getAlbumId, id));
        this.albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, id));

        //发送消息，同步es数据
        this.rabbitmqService.sendMqMsg(TingShuMqConstants.ALBUM_EXCHANGE, TingShuMqConstants.ALBUM_DELETE_RK, id);
    }

    @Override
    @TingShuCache(cachePrefix = RedisConstant.ALBUM_INFO_PREFIX, bloomFilter = RedisConstant.ALBUM_BLOOM_FILTER, lockPrefix = RedisConstant.ALBUM_LOCK_PREFIX)
    public AlbumInfo getAlbumInfo(Long id) {
        AlbumInfo albumInfo = this.getById(id);
        if (albumInfo != null) {
            List<AlbumAttributeValue> albumAttributeValues = this.albumAttributeValueMapper.selectList(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, id));
            albumInfo.setAlbumAttributeValueVoList(albumAttributeValues);
        }
        return albumInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAlbumInfo(Long id, AlbumInfoVo albumInfoVo) {
        //保存基本信息
        AlbumInfo albumInfo = new AlbumInfo();
        BeanUtils.copyProperties(albumInfoVo, albumInfo);
        albumInfo.setId(id);
        updateById(albumInfo);
        //删除旧专辑标签值
        this.albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, id));
        //保存修改后的专辑标签值
        this.saveAlbumAttributeValue(albumInfoVo, id);

        //发送消息，同步es数据
        if (albumInfo.getIsOpen().equals("1")) {
            this.rabbitmqService.sendMqMsg(TingShuMqConstants.ALBUM_EXCHANGE, TingShuMqConstants.ALBUM_SAVE_UPDATE_RK, id);
        }
    }

    @Override
    public List<AlbumInfo> findUserAllAlbumList(Long userId) {
        return this.baseMapper.selectList(new LambdaQueryWrapper<AlbumInfo>().eq(AlbumInfo::getUserId, userId).select(AlbumInfo::getId, AlbumInfo::getAlbumTitle).orderByDesc(AlbumInfo::getId));
    }

    @Override
    public AlbumListVo findUserAlbum(Long albumId) {
        return this.baseMapper.findUserAlbum(albumId);
    }

    @Override
    public List<AlbumListVo> findAllAlbumPage(Integer page, Integer limit) {
        IPage<AlbumListVo> iPage = new Page<>(page, limit);
        IPage<AlbumListVo> userAlbumPage = this.baseMapper.findUserAlbumPage(iPage, new AlbumInfoQuery());
        return userAlbumPage.getRecords();
    }

    @Override
    public List<Long> getChangeAlbum(String startTime, String endTime) {
        List<AlbumStat> albumStats = this.albumStatMapper.selectList(new LambdaQueryWrapper<AlbumStat>()
                .between(AlbumStat::getUpdateTime, startTime, endTime).select(AlbumStat::getAlbumId));
        if (CollectionUtils.isEmpty(albumStats)) return null;
        return albumStats.stream().distinct().map(AlbumStat::getAlbumId).toList();
    }

    @Override
    public List<AlbumStatVo> getChangeAlbumStats(List<Long> albumIds) {
        return this.baseMapper.getChangeAlbumStat(albumIds);
    }


    //保存专辑标签值的方法
    private void saveAlbumAttributeValue(AlbumInfoVo albumInfoVo, Long albumInfoId) {
        List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
        if (!CollectionUtils.isEmpty(albumAttributeValueVoList)) {
            albumAttributeValueVoList.forEach(albumAttributeValueVo -> {
                AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
                BeanUtils.copyProperties(albumAttributeValueVo, albumAttributeValue);
                albumAttributeValue.setAlbumId(albumInfoId);
                this.albumAttributeValueMapper.insert(albumAttributeValue);
            });
        }
    }

    //初始化专辑统计表的方法
    public void initAlbumStat(Long albumId, String statType) {
        AlbumStat albumStat = new AlbumStat();
        albumStat.setAlbumId(albumId);
        albumStat.setStatType(statType);
        albumStat.setStatNum(0);
        this.albumStatMapper.insert(albumStat);
    }
}
